/*
 * board.c
 *
 *  Created on: Mar 27, 2013
 *      Author: locpx
 */
#include "stdio.h"
#include "extglobals.h"
#include "board.h"
#include "protos.h"

void initBoard(BOARD* m_board)
{
	m_board->nextMove = WHITE_MOVE;
	m_board->viewRotated = FALSE;

	int i;
	for (i = 0; i < 90; i++)
	{
		m_board->square[i] = EMPTY;
	}

	// RHEAKAEHR
	m_board->square[A0] = WHITE_ROOK;
	m_board->square[B0] = WHITE_HORSE;
	m_board->square[C0] = WHITE_ELEPHANT;
	m_board->square[D0] = WHITE_ADVISOR;
	m_board->square[E0] = WHITE_KING;
	m_board->square[F0] = WHITE_ADVISOR;
	m_board->square[G0] = WHITE_ELEPHANT;
	m_board->square[H0] = WHITE_HORSE;
	m_board->square[I0] = WHITE_ROOK;

	// rheakaehr
	m_board->square[A9] = BLACK_ROOK;
	m_board->square[B9] = BLACK_HORSE;
	m_board->square[C9] = BLACK_ELEPHANT;
	m_board->square[D9] = BLACK_ADVISOR;
	m_board->square[E9] = BLACK_KING;
	m_board->square[F9] = BLACK_ADVISOR;
	m_board->square[G9] = BLACK_ELEPHANT;
	m_board->square[H9] = BLACK_HORSE;
	m_board->square[I9] = BLACK_ROOK;

	// 1C5C1
	m_board->square[B2] = WHITE_CANNON;
	m_board->square[H2] = WHITE_CANNON;

	// 1c5c1
	m_board->square[B7] = BLACK_CANNON;
	m_board->square[H7] = BLACK_CANNON;

	// P1P1P1P1P
	m_board->square[A3] = WHITE_PAWN;
	m_board->square[C3] = WHITE_PAWN;
	m_board->square[E3] = WHITE_PAWN;
	m_board->square[G3] = WHITE_PAWN;
	m_board->square[I3] = WHITE_PAWN;

	// p1p1p1p1p1
	m_board->square[A6] = BLACK_PAWN;
	m_board->square[C6] = BLACK_PAWN;
	m_board->square[E6] = BLACK_PAWN;
	m_board->square[G6] = BLACK_PAWN;
	m_board->square[I6] = BLACK_PAWN;

	initBoardFromSquares(m_board, m_board->square, WHITE_MOVE);

	return;
}

void displayBoard(BOARD m_board)
{
	int rank, file;
	if (m_board.viewRotated)
	{
		printf("  i h g f e d c b a\n");
		printf("-|-----------------|-\n");
		for (rank = 0; rank < 10; rank++)
		{
			for (file = 8; file >= 0; file--)
			{
				if (file == 8)
					printf(" |%c", PIECENAMES[m_board.square[BOARDINDEX[file][rank]]]);
				else
					printf(" %c", PIECENAMES[m_board.square[BOARDINDEX[file][rank]]]);
			}
			printf("|%d", rank);
			printf("\n");
		}
		printf("-|-----------------|-\n");
	}
	else
	{
		printf("-|-----------------|-\n");
		for (rank = 9; rank >= 0; rank--)
		{
			printf("%d|", rank);
			for (file = 0; file < 9; file++)
			{
				if (file < 8)
					printf("%c ", PIECENAMES[m_board.square[BOARDINDEX[file][rank]]]);
				else
					printf("%c", PIECENAMES[m_board.square[BOARDINDEX[file][rank]]]);
			}
			printf("|\n");
		}
		printf("-|-----------------|-\n");
		printf("  a b c d e f g h i\n");
	}

	return;
}

void initBoardFromSquares(BOARD* m_board, int m_square[90], unsigned char m_nextMove)
{
	// sets up the board variables according to the information found in the square[90] array

	// setting all bits to 0
	clearBitBoard(&m_board->whiteKing);
	clearBitBoard(&m_board->whiteAdvisors);
	clearBitBoard(&m_board->whiteElephants);
	clearBitBoard(&m_board->whiteRooks);
	clearBitBoard(&m_board->whiteCannons);
	clearBitBoard(&m_board->whiteHorses);
	clearBitBoard(&m_board->whitePawns);

	clearBitBoard(&m_board->blackKing);
	clearBitBoard(&m_board->blackAdvisors);
	clearBitBoard(&m_board->blackElephants);
	clearBitBoard(&m_board->blackRooks);
	clearBitBoard(&m_board->blackCannons);
	clearBitBoard(&m_board->blackHorses);
	clearBitBoard(&m_board->blackPawns);

	// populate all bitboards:
	int i;
	for (i = 0; i < 90; i++)
	{
		m_board->square[i] = m_square[i];

		if (m_square[i] == WHITE_KING)
			m_board->whiteKing = orTwoBitBoards(m_board->whiteKing, BITBOARDSET[i]);
		if (m_square[i] == WHITE_ADVISOR)
			m_board->whiteAdvisors = orTwoBitBoards(m_board->whiteAdvisors, BITBOARDSET[i]);
		if (m_square[i] == WHITE_ELEPHANT)
			m_board->whiteElephants = orTwoBitBoards(m_board->whiteElephants, BITBOARDSET[i]);
		if (m_square[i] == WHITE_ROOK)
			m_board->whiteRooks = orTwoBitBoards(m_board->whiteRooks, BITBOARDSET[i]);
		if (m_square[i] == WHITE_CANNON)
			m_board->whiteCannons = orTwoBitBoards(m_board->whiteCannons, BITBOARDSET[i]);
		if (m_square[i] == WHITE_HORSE)
			m_board->whiteHorses = orTwoBitBoards(m_board->whiteHorses, BITBOARDSET[i]);
		if (m_square[i] == WHITE_PAWN)
			m_board->whitePawns = orTwoBitBoards(m_board->whitePawns, BITBOARDSET[i]);

		if (m_square[i] == BLACK_KING)
			m_board->blackKing = orTwoBitBoards(m_board->blackKing, BITBOARDSET[i]);
		if (m_square[i] == BLACK_ADVISOR)
			m_board->blackAdvisors = orTwoBitBoards(m_board->blackAdvisors, BITBOARDSET[i]);
		if (m_square[i] == BLACK_ELEPHANT)
			m_board->blackElephants = orTwoBitBoards(m_board->blackElephants, BITBOARDSET[i]);
		if (m_square[i] == BLACK_ROOK)
			m_board->blackRooks = orTwoBitBoards(m_board->blackRooks, BITBOARDSET[i]);
		if (m_square[i] == BLACK_CANNON)
			m_board->blackCannons = orTwoBitBoards(m_board->blackCannons, BITBOARDSET[i]);
		if (m_square[i] == BLACK_HORSE)
			m_board->blackHorses = orTwoBitBoards(m_board->blackHorses, BITBOARDSET[i]);
		if (m_square[i] == BLACK_PAWN)
			m_board->blackPawns = orTwoBitBoards(m_board->blackPawns, BITBOARDSET[i]);
	}

	BITBOARD whitePieces[] = {m_board->whiteKing, m_board->whiteAdvisors, m_board->whiteElephants,
			m_board->whiteRooks, m_board->whiteCannons, m_board->whiteHorses, m_board->whitePawns
	};
	m_board->whitePieces = orMultipleBitBoards(whitePieces, 7);

	BITBOARD blackPieces[] = {m_board->blackKing, m_board->blackAdvisors, m_board->blackElephants,
			m_board->blackRooks, m_board->blackCannons, m_board->blackHorses, m_board->blackPawns
	};
	m_board->blackPieces = orMultipleBitBoards(blackPieces, 7);

	m_board->occupiedSquares = orTwoBitBoards(m_board->whitePieces, m_board->blackPieces);

	m_board->nextMove = m_nextMove;

	m_board->searchDepth = DEFAULT_SEARCH_DEPTH;

	m_board->timer.startTime = 0;
	m_board->timer.stopTime = 0;
	m_board->timer.stopTimeDelta = 0;
	m_board->timer.running = FALSE;

	return;
}
